"""
*args and **kwargs allow a function to collect extra (except required) arguments(as a tuple)
so you can create flexible APIs in your modules and classes
required -- can be ignored
*args collect extra positional arguments as a tuple
**kwargs collect extra keyword arguments as a dictionary
"""


def foo(required, *args, **kwargs):
    """check the paras which *args and **kwargs collect"""
    print(required)
    if args:
        print(args)
    if kwargs:
        print(kwargs)
        kwargs['key1'] = 'value1'
        kwargs['key2'] -= 1
        test_kwargs_modify(**kwargs)


def test_kwargs_modify(**kwargs):
    print(kwargs)


if __name__ == '__main__':
    # TypeError: foo() missing 1 required positional argument: 'required'
    # foo()
    foo('hi', 1, 2, 3, key1='value', key2=1000)